home *** CD-ROM | disk | FTP | other *** search
/ Turnbull China Bikeride / Turnbull China Bikeride - Disc 2.iso / ACORNUSERS / CBSA / COMPUTER / WIMP2 / !Wimp2Ctrl / c / !RunImage
Text File  |  1999-03-20  |  16KB  |  603 lines

  1. /* !RunImage.c
  2. Wimp2 task control
  3. by N. Douglas
  4. Started: 08-01-1999
  5. Last updated: 26-01-1999 version 0.27
  6. */
  7.  
  8. #include "kernel.h"
  9. #include <stdio.h>
  10. #include <stdlib.h>
  11. #include <string.h>
  12.  
  13. #define BOOL char
  14. #define FALSE 0
  15. #define TRUE 1
  16.  
  17. static BOOL quit=FALSE;
  18. static char indir[8192], *indirptr;
  19. static char templ[1024];
  20. static char menus[512];
  21. static int windh;
  22. static int maxic=0;
  23.  
  24. #define XOR_SPECIAL 0x1d872b41
  25. static unsigned int seed=0xabcdef12;
  26.  
  27. static int codeshandler(int, int);
  28. static int codeshandler2(int, int);
  29. static void CopyLine(int, char *, char *, char *, char *, char *, char *);
  30. int ROReportError(int flags, int *blk);
  31. int ROReportErrora(int flags, int errno, char *errstr);
  32. void StdErrHandlr(_kernel_oserror *);
  33. unsigned int rnd(int);
  34.  
  35. int main(void)
  36. {
  37.   char taskname[]="Wimp2 Task Manager";
  38.   char q[256];
  39.   _kernel_swi_regs r;
  40.   int a;
  41.   int tbefore=0,tafter=1,tinc=100;
  42.   BOOL update=TRUE;
  43.   int totaltasks=0;
  44.   long int selectedtask=0;
  45.  
  46.   r.r[0]=200;
  47.   r.r[1]=0x4b534154;
  48.   r.r[2]=(int) taskname;
  49.   StdErrHandlr(_kernel_swi(0x400c0/*Wimp_Initialise*/, &r, &r));
  50.  
  51.   /* Load some templates */
  52.   {
  53.     const char templatenm[]="<Wimp2Ctrl$Dir>.Templates";
  54.     const char main[]="main";
  55.  
  56.     r.r[1]=(int) templatenm;
  57.     StdErrHandlr(_kernel_swi(0x400d9/*Wimp_OpenTemplate*/, &r, &r));
  58.  
  59.     r.r[1]=(int) templ;
  60.     r.r[2]=(int) indir;
  61.     r.r[3]=(int) indir+8192;
  62.     r.r[4]=-1;
  63.     r.r[5]=(int) main;
  64.     r.r[6]=0;
  65.     StdErrHandlr(_kernel_swi(0x400db/*Wimp_LoadTemplate*/, &r, &r));
  66.     maxic=*(int *)(templ+84);
  67.     StdErrHandlr(_kernel_swi(0x400c1/*Wimp_CreateWindow*/, &r, &r));
  68.     windh=r.r[0];
  69.     indirptr=(char *) r.r[2];
  70.  
  71.     StdErrHandlr(_kernel_swi(0x400da/*Wimp_CloseTemplate*/, &r, &r));
  72.   }
  73.  
  74.   StdErrHandlr(_kernel_swi(0x42/*OS_ReadMonotonicTime*/, &r, &r));
  75.   seed=r.r[0];
  76.  
  77.   r.r[1]=(int) q;
  78.   *(int *)(q+0)=windh;
  79.   StdErrHandlr(_kernel_swi(0x400cb/*Wimp_GetWindowState*/, &r, &r));
  80.   {
  81.     int dx=(*(int *)(q+12))-(*(int *)(q+4)),dy=(*(int *)(q+16))-(*(int *)(q+8));
  82.     *(int *)(q+4)=rnd(640);
  83.     *(int *)(q+8)=rnd(512);
  84.     *(int *)(q+12)=(*(int *)(q+4))+dx;
  85.     *(int *)(q+16)=(*(int *)(q+8))+dy;
  86.   }
  87.   StdErrHandlr(_kernel_swi(0x400c5/*Wimp_OpenWindow*/, &r, &r));
  88.  
  89.   CopyLine(6,"-","Other tasks", "-", "-", "-", "-");
  90.  
  91.   /* Enter main message loop */
  92.   do
  93.   {
  94.     /* Update lists */
  95.     if(update)
  96.     {
  97.       int timeused=0;
  98.       int topic=6,line,newtotaltasks=0;
  99.       double usused;
  100.       char tusage[16];
  101.       char tsused[16];
  102.       r.r[0]=0;
  103.       for(line=2;line<3+totaltasks;line++)
  104.       {
  105.         char taskh[12]="", usage[8]="", threads[16]="", sused[12]="", smax[12]="";
  106.         if(r.r[0]>=0) StdErrHandlr(_kernel_swi(0xc004d/*Wimp2_EnumerateTasks*/, &r, &r));
  107.         if(r.r[0]>=0)
  108.         {
  109.           _kernel_swi_regs r2;
  110.           r2.r[1]=r.r[1];
  111.           r2.r[4]=0;
  112.           r2.r[5]=0;
  113.           _kernel_swi(0xc004e/*Wimp2_SetTaskData*/, &r2, &r2);
  114.  
  115.           newtotaltasks++;
  116.           sprintf(taskh, "%08x", r.r[1]);
  117.           if(tafter-tbefore==0)
  118.             usused=0;
  119.           else
  120.             usused=(r.r[5]*10.0)/(tafter-tbefore);
  121.           sprintf(usage, "%.1f%%", usused);
  122.           sprintf(smax,"%d", r.r[4]);
  123.           sprintf(sused, "%d", r.r[5]);
  124.           sprintf(threads,"%d", r.r[6]);
  125.           timeused+=r.r[5];
  126.           CopyLine(topic*line, taskh, (char *) r.r[3], usage, threads, sused, smax);
  127.         }
  128.         else
  129.           CopyLine(topic*line, NULL, NULL, NULL, NULL, NULL, NULL);
  130.       }
  131.       if(tafter-tbefore==0)
  132.         usused=0;
  133.       else
  134.         usused=(timeused*10.0)/(tafter-tbefore);
  135.       {
  136.         int na;
  137.         na=(int)(usused*10.0);
  138.         na=1000-na;
  139.         usused=na/10.0;
  140.       }
  141.       sprintf(tusage,"%.1f%%",usused);
  142.       sprintf(tsused,"%d", (tafter-tbefore)*10-timeused);
  143.       CopyLine(topic,"-","Normal tasks", tusage, "-", tsused, "-");
  144.  
  145.       /* Update window */
  146.       *(int *)(q+0)=windh;
  147.       *(int *)(q+4)=0;
  148.       *(int *)(q+8)=-1792;
  149.       *(int *)(q+12)=1096;
  150.       *(int *)(q+16)=0;
  151.       r.r[1]=(int) q;
  152.       StdErrHandlr(_kernel_swi(0x400c9/*Wimp_UpdateWindow*/, &r, &r));
  153.       while(r.r[0])
  154.         StdErrHandlr(_kernel_swi(0x400ca/*Wimp_GetRectangle*/, &r, &r));
  155.  
  156.       totaltasks=newtotaltasks;
  157.       StdErrHandlr(_kernel_swi(0x42/*OS_ReadMonotonicTime*/, &r, &r));
  158.       tbefore=r.r[0];
  159.     }
  160.  
  161.     r.r[0]=0;
  162.     r.r[1]=(int) q;
  163.     r.r[2]=tbefore+tinc;
  164.     StdErrHandlr(_kernel_swi(0x400e1/*Wimp_PollIdle*/, &r, &r));
  165.     a=r.r[0];
  166.     StdErrHandlr(_kernel_swi(0x42/*OS_ReadMonotonicTime*/, &r, &r));
  167.     if(r.r[0]>=tbefore+tinc)
  168.     {
  169.       tafter=r.r[0];
  170.       update=TRUE;
  171.     }
  172.     else update=FALSE;
  173.  
  174.     switch(a)
  175.     {
  176.       case 2:
  177.       StdErrHandlr(_kernel_swi(0x400c5/*Wimp_OpenWindow*/, &r, &r));
  178.       break;
  179.       case 3:
  180.       {
  181.         StdErrHandlr(_kernel_swi(0x400c6/*Wimp_CloseWindow*/, &r, &r));
  182.         if(*(int *)(r.r[1])==windh) quit=TRUE;
  183.         break;
  184.       }
  185.       case 6:
  186.       if((*(int *)(q+12))==-2)/*ie; the icon bar*/
  187.       {
  188.         if((*(int *)(q+8) & 4)==4)
  189.         {
  190.           /* Open the window */
  191.           *(int *)(q+0)=windh;
  192.           r.r[1]=(int) q;
  193.           StdErrHandlr(_kernel_swi(0x400cb/*Wimp_GetWindowState*/, &r, &r));
  194.           *(int *)(q+28)=-1;
  195.           StdErrHandlr(_kernel_swi(0x400c5/*Wimp_OpenWindow*/, &r, &r));
  196.         }
  197.         else
  198.         {
  199.           StdErrHandlr(_kernel_swi(0x107, &r, &r));
  200.         }
  201.         break;
  202.       }
  203.       else if((*(int *)(q+12))==windh) /* ie; it's the window */
  204.       {
  205.         if((*(int *)(q+8) & 2)==2)
  206.         {
  207.           int baseic;
  208.           /* Open menu */
  209.  
  210.           /* Deduce where the mouse pointer is */
  211.           if(*(int *)(q+16)!=-1)
  212.           {
  213.             baseic=*(int *)(q+16);
  214.             baseic=baseic/6;
  215.             if(baseic<=1) baseic=0;
  216.             baseic=baseic*6;
  217.           }
  218.           else
  219.             baseic=0;
  220.           if(baseic>0)
  221.           {
  222.             const char menuname[]="Wimp2Ctrl";
  223.             const char setslice[]="Set Slice";
  224.             const char killtask[]="Kill Task";
  225.             char *menuptr, *menu2, *end;
  226.  
  227.             /* Set baseic */
  228.             *(int *)(q+128)=windh;
  229.             *(int *)(q+128+4)=baseic;
  230.             r.r[1]=(int) q+128;
  231.             _kernel_swi(0x400ce/*Wimp_GetIconState*/, &r, &r);
  232.             selectedtask=strtoul((char *)(*(int *)(q+128+8+20)), &end, 16);
  233.  
  234.             /*Create a submenu */
  235.             menu2=menus+256;
  236.             {
  237.               char *menu2ptr;
  238.               const char menuname[]="Priority";
  239.               const char lowp[]="Low";
  240.               const char normalp[]="Normal";
  241.               const char highp[]="High";
  242.               const char ouchp[]="Ouch!";
  243.               const char writeablel[]="A0-9";
  244.  
  245.               *(int *)(menu2+0)=*(int *)(menuname+0);
  246.               *(int *)(menu2+4)=*(int *)(menuname+4);
  247.               *(int *)(menu2+8)=*(int *)(menuname+8);
  248.               *(char *)(menu2+12)=7;
  249.               *(char *)(menu2+13)=2;
  250.               *(char *)(menu2+14)=7;
  251.               *(char *)(menu2+15)=0;
  252.               *(int *)(menu2+16)=4*16;
  253.               *(int *)(menu2+20)=44;
  254.               *(int *)(menu2+24)=0;
  255.               menu2ptr=menu2+28;
  256.  
  257.               *(int *)(menu2ptr+0)=0x0;
  258.               *(int *)(menu2ptr+4)=-1;
  259.               *(int *)(menu2ptr+8)=0x7005031;
  260.               *(int *)(menu2ptr+12)=*(int *)(lowp+0);
  261.               *(int *)(menu2ptr+16)=*(int *)(lowp+4);
  262.               *(int *)(menu2ptr+20)=*(int *)(lowp+8);
  263.               menu2ptr+=24;
  264.               *(int *)(menu2ptr+0)=0x0;
  265.               *(int *)(menu2ptr+4)=-1;
  266.               *(int *)(menu2ptr+8)=0x7005031;
  267.               *(int *)(menu2ptr+12)=*(int *)(normalp+0);
  268.               *(int *)(menu2ptr+16)=*(int *)(normalp+4);
  269.               *(int *)(menu2ptr+20)=*(int *)(normalp+8);
  270.               menu2ptr+=24;
  271.               *(int *)(menu2ptr+0)=0x0;
  272.               *(int *)(menu2ptr+4)=-1;
  273.               *(int *)(menu2ptr+8)=0x7005031;
  274.               *(int *)(menu2ptr+12)=*(int *)(highp+0);
  275.               *(int *)(menu2ptr+16)=*(int *)(highp+4);
  276.               *(int *)(menu2ptr+20)=*(int *)(highp+8);
  277.               menu2ptr+=24;
  278.               *(int *)(menu2ptr+0)=0x0;
  279.               *(int *)(menu2ptr+4)=-1;
  280.               *(int *)(menu2ptr+8)=0x7005031;
  281.               *(int *)(menu2ptr+12)=*(int *)(ouchp+0);
  282.               *(int *)(menu2ptr+16)=*(int *)(ouchp+4);
  283.               *(int *)(menu2ptr+20)=*(int *)(ouchp+8);
  284.               menu2ptr+=24;
  285.               *(int *)(menu2ptr+0)=0x84;
  286.               *(int *)(menu2ptr+4)=-1;
  287.               *(int *)(menu2ptr+8)=0x7009131;
  288.               *(int *)(menu2ptr+12)=(int) menus+500;
  289.               *(int *)(menu2ptr+16)=(int) writeablel;
  290.               *(int *)(menu2ptr+20)=4;
  291.               menu2ptr+=24;
  292.             }
  293.  
  294.             /*Open a quit menu */
  295.             *(int *)(menus+0)=*(int *)(menuname+0);
  296.             *(int *)(menus+4)=*(int *)(menuname+4);
  297.             *(int *)(menus+8)=*(int *)(menuname+8);
  298.             *(char *)(menus+12)=7;
  299.             *(char *)(menus+13)=2;
  300.             *(char *)(menus+14)=7;
  301.             *(char *)(menus+15)=0;
  302.             *(int *)(menus+16)=4*16;    /* I see this is ignored on RO3 */
  303.             *(int *)(menus+20)=44;
  304.             *(int *)(menus+24)=0;
  305.             menuptr=menus+28;
  306.  
  307.             *(int *)(menuptr+0)=0x0;
  308.             *(int *)(menuptr+4)=(int) menu2;
  309.             *(int *)(menuptr+8)=0x7005031;
  310.             *(int *)(menuptr+12)=*(int *)(setslice+0);
  311.             *(int *)(menuptr+16)=*(int *)(setslice+4);
  312.             *(int *)(menuptr+20)=*(int *)(setslice+8);
  313.             menuptr+=24;
  314.             *(int *)(menuptr+0)=0x80;
  315.             *(int *)(menuptr+4)=-1;
  316.             *(int *)(menuptr+8)=0x7005031 | (1<<22);
  317.             *(int *)(menuptr+12)=*(int *)(killtask+0);
  318.             *(int *)(menuptr+16)=*(int *)(killtask+4);
  319.             *(int *)(menuptr+20)=*(int *)(killtask+8);
  320.             r.r[1]=(int) menus;
  321.             r.r[2]=(*(int *)(q+0))-64;
  322.             r.r[3]=(*(int *)(q+4))+24;
  323.             StdErrHandlr(_kernel_swi(0x400d4/*Wimp_CreateMenu*/, &r, &r));
  324.           }
  325.           else
  326.             _kernel_swi(0x107, &r, &r);
  327.         }
  328.         break;
  329.       }
  330.       break;
  331.       case 9:
  332.       {
  333.         switch(*(int *)(q+0))
  334.         {
  335.           case 0: /* set slice */
  336.           {
  337.             r.r[1]=(int) selectedtask;
  338.             r.r[5]=-1;
  339.             switch(*(int *)(q+4))
  340.             {
  341.               case 0: /* Low */
  342.               {
  343.                 r.r[4]=2;
  344.                 break;
  345.               }
  346.               case 1: /* Normal */
  347.               {
  348.                 r.r[4]=5;
  349.                 break;
  350.               }
  351.               case 2: /* High */
  352.               {
  353.                 r.r[4]=25;
  354.                 break;
  355.               }
  356.               case 3: /* Ouch! */
  357.               {
  358.                 r.r[4]=100;
  359.                 break;
  360.               }
  361.               case 4: /* User defined */
  362.               {
  363.                 r.r[4]=atoi(menus+500);
  364.                 break;
  365.               }
  366.               default:
  367.               {
  368.                 r.r[4]=0;
  369.                 break;
  370.               }
  371.             }
  372.             _kernel_swi(0xc004e/*Wimp2_SetTaskData*/, &r, &r);
  373.             break;
  374.           }
  375.           case 1: /* kill task */
  376.           {
  377.             r.r[0]=(int) selectedtask;
  378.             _kernel_swi(0xc004f/*Wimp2_KillProcess*/, &r, &r);
  379.             break;
  380.           }
  381.         }
  382.         break;
  383.       }
  384.       case 17:
  385.       case 18:
  386.       switch(*(int *) (r.r[1]+16))
  387.       {
  388.         default:
  389.         {
  390.           codeshandler(a, r.r[1]);
  391.           break;
  392.         }
  393.       }
  394.       break;
  395.       default:
  396.       break;
  397.     }
  398.   }
  399.   while(!quit);
  400.  
  401.   /* Shut her down */
  402.   r.r[1]=0;
  403.   _kernel_swi(0x400dd/*Wimp_CloseDown*/, &r, &r);
  404.  
  405.   return 0;
  406. }
  407.  
  408. void CopyLine(int startic, char *pid, char *name, char *usage, char *memory, char *sused, char *smax)
  409. {
  410.   char q[256];
  411.   _kernel_swi_regs r;
  412.   int n;
  413.   BOOL del=FALSE;
  414.  
  415.   if(pid==NULL && name==NULL && usage==NULL && memory==NULL && sused==NULL && smax==NULL) del=TRUE;
  416.  
  417.   for(n=startic; n<startic+6;n++)
  418.   {
  419.     BOOL change=FALSE;
  420.     if(n>=maxic)
  421.     {
  422.       int a;
  423.       for(a=0; a<6;a++)
  424.       {
  425.         *(int *)(q+0)=windh;
  426.         *(int *)(q+4)=a;
  427.         r.r[1]=(int) q;
  428.         _kernel_swi(0x400ce/*Wimp_GetIconState*/, &r, &r);
  429.         *(int *)(q+4)=windh;
  430.         (*(int *)(q+8+4))-=56*n/6;
  431.         (*(int *)(q+8+12))-=56*n/6;
  432.         memset(indirptr, 0, *(int *)(q+8+28));
  433.         *(int *)(q+8+20)=(int) indirptr;
  434.         indirptr+=*(int *)(q+8+28);
  435.         r.r[1]=(int) q+4;
  436.         _kernel_swi(0x400c2/*Wimp_CreateIcon*/, &r, &r);
  437.         if(r.r[0]+1>maxic) maxic=r.r[0]+1;
  438.       }
  439.     }
  440.     *(int *)(q+0)=windh;
  441.     *(int *)(q+4)=n;
  442.     r.r[1]=(int) q;
  443.     _kernel_swi(0x400ce/*Wimp_GetIconState*/, &r, &r);
  444.     if(del==TRUE && ((*(int *)(q+8+16)) & (1<<23))==0) change=TRUE;
  445.     if(del==FALSE && ((*(int *)(q+8+16)) & (1<<23))!=0) change=TRUE;
  446.     if(change)
  447.     {
  448.       int clear,eor;
  449.       if(del)
  450.       {
  451.         clear=1<<23;
  452.         eor=1<<23;
  453.       }
  454.       else
  455.       {
  456.         eor=0;
  457.         clear=1<<23;
  458.       }
  459.       *(int *)(q+0)=windh;
  460.       *(int *)(q+4)=n;
  461.       *(int *)(q+8)=eor;
  462.       *(int *)(q+12)=clear;
  463.       r.r[1]=(int) q;
  464.       _kernel_swi(0x400cd/*Wimp_SetIconState*/, &r, &r);
  465.       /* And redraw everything */
  466.       r.r[0]=windh;
  467.       r.r[1]=0;
  468.       r.r[2]=-1792;
  469.       r.r[3]=1096;
  470.       r.r[4]=0;
  471.       _kernel_swi(0x400d1/*Wimp_ForceRedraw*/, &r, &r);
  472.     }
  473.     {
  474.       switch(n % 6)
  475.       {
  476.         case 0:
  477.         {
  478.           strcpy((char *)(*(int *)(q+8+20)), pid);
  479.           break;
  480.         }
  481.         case 1:
  482.         {
  483.           strcpy((char *)(*(int *)(q+8+20)), name);
  484.           break;
  485.         }
  486.         case 2:
  487.         {
  488.           strcpy((char *)(*(int *)(q+8+20)), usage);
  489.           break;
  490.         }
  491.         case 3:
  492.         {
  493.           strcpy((char *)(*(int *)(q+8+20)), memory);
  494.           break;
  495.         }
  496.         case 4:
  497.         {
  498.           strcpy((char *)(*(int *)(q+8+20)), sused);
  499.           break;
  500.         }
  501.         case 5:
  502.         {
  503.           strcpy((char *)(*(int *)(q+8+20)), smax);
  504.           break;
  505.         }
  506.       }
  507.     }
  508.   }
  509. }
  510.  
  511. int codeshandler(int msgno, int msgblk)
  512. {
  513.   /*return 2;*/
  514.   return codeshandler2(msgno, msgblk);
  515. }
  516.  
  517. int codeshandler2(int msgno, int msgblk)
  518. {
  519.   switch(*(int *) (msgblk+16))
  520.   {
  521.     case 0:
  522.     quit=TRUE;
  523.     return 1;
  524.     break;
  525.     case 0x502:/*Message_HelpRequest*/
  526.     if(*(int *)(msgblk+32)==windh)
  527.     {
  528.       char msg[]="This is a list of tasks being preemptively multitasked by Wimp2 and information about them. Click MENU to alter the configuration of the task.";
  529.       _kernel_swi_regs r;
  530.  
  531.       strcpy((char *) msgblk+20,msg);
  532.       *(int *)(msgblk+0)=256;
  533.       *(int *)(msgblk+16)=0x503;/*Message_HelpGive*/
  534.       *(int *)(msgblk+12)=*(int *)(msgblk+8);
  535.       r.r[0]=17;
  536.       r.r[1]=msgblk;
  537.       r.r[2]=*(int *)(msgblk+4);
  538.       _kernel_swi(0x400e7/*Wimp_SendMessage*/, &r, &r);
  539.       return 1;
  540.     }
  541.     return 0;
  542.     break;
  543.     default:
  544.     return 0;
  545.     break;
  546.   }
  547. }
  548.  
  549. unsigned int rnd(int val)
  550. {
  551.   int n;
  552.  
  553.   for(n=0;n<32;n++)
  554.   {
  555.     seed=seed<<1;
  556.     if(seed & (1<<30))
  557.     {
  558.       seed=seed^XOR_SPECIAL;
  559.     }
  560.   }
  561.   n=seed % val;
  562.   if(n>=0)
  563.     return n;
  564.   else
  565.     return -n;
  566. }
  567.  
  568. int ROReportError(int flags, int *blk)
  569. {
  570.   _kernel_swi_regs r;
  571.   char tmesg[]="Wimp2 Demo";
  572.  
  573.   r.r[0]=(int) blk;
  574.   r.r[1]=flags;
  575.   r.r[2]=(int) tmesg;
  576.   _kernel_swi(0x400df/*Wimp_ReportError*/, &r, &r);
  577.  
  578.   if(flags & 0x100)
  579.     exit(EXIT_FAILURE);
  580.   return r.r[1];
  581. }
  582.  
  583. int ROReportErrora(int flags, int errno, char *errstr)
  584. {
  585.   char q[260];
  586.  
  587.   *(int *)(q+0)=errno;
  588.   strcpy((q+4), errstr);
  589.   return ROReportError(flags, (int *) q);
  590. }
  591.  
  592. void StdErrHandlr(_kernel_oserror *blk)
  593. {
  594.   if(blk)
  595.     ROReportError(0x102, (int *) blk);
  596. }
  597.  
  598.  
  599. /* Just for debugging purposes */
  600. void end(void)
  601. {
  602. }
  603.